//
//  TodayViewController.swift
//  UIC Timetable
//
//  Created by 高宇超 on 7/20/17.
//  Copyright © 2017 Yuchao. All rights reserved.
//

import UIKit
import NotificationCenter
import RealmSwift


// tap show more to change presentation mode
// show more for tableview, show less for only next class
class TodayViewController: UIViewController, NCWidgetProviding, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var loadingLabel: UILabel!
    
    var timetables = [ClassOneRealm]()
    var firstLoad = true
    var lastMinute = 0
    var lastWeekday = 0
    
    var user: UserRealm?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.extensionContext?.widgetLargestAvailableDisplayMode = .expanded // show "Show More/Less" button

        Realm.Configuration.defaultConfiguration.fileURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.uicportal")?.appendingPathComponent("default.realm")
        if let user = RealmHelper.retrieveLastUser() {
            self.user = user
            updateTimetable()
            firstLoad = false
        } else {
            loadingLabel.text = "Please login first."
        }
    }
    
    func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        // Perform any setup necessary in order to update the view.
        if let _ = RealmHelper.retrieveLastUser() {
            let currentWeekday = Calendar.current.component(.weekday, from: Date())
            let currentMinute = Calendar.current.component(.minute, from: Date())
            if currentMinute != lastMinute || currentWeekday != lastWeekday {
                if timetables.count > 0 {
                    updateTimetable()
                    completionHandler(NCUpdateResult.newData)
                } else if firstLoad {
                    updateTimetable()
                    completionHandler(NCUpdateResult.newData)
                }
            }
        } else {
            completionHandler(NCUpdateResult.noData)
        }
    }

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
        switch activeDisplayMode {
        case .compact:
            self.preferredContentSize = CGSize(width: maxSize.width, height: 104)
        case .expanded:
            self.preferredContentSize = CGSize(width: maxSize.width, height: 208)
        }
    }
    
    func updateTimetable() {
        guard let user = self.user else { return }
        tableView.isHidden = false
        loadingLabel.isHidden = true
        timetables.removeAll()
        let date = Date()
        let currentWeekday = Calendar.current.component(.weekday, from: date)
        let currentTimeHour = Calendar.current.component(.hour, from: date)
        var classesPast = [ClassOneRealm]()
        let classesOne = RealmHelper.retrieveAllClassesOne(user: user.username)
        for classOne in classesOne {
            guard let weekday = classOne.weekday else { break }
            guard let classWeekday = weekdayDict[weekday] else { break }
            let endTime = classOne.endTime
            
            if classWeekday < currentWeekday {
                classesPast.append(classOne)
            } else if classWeekday == currentWeekday {
                if endTime <= currentTimeHour {
                    classesPast.append(classOne)
                } else {
                    timetables.append(classOne)
                }
            } else {
                timetables.append(classOne)
            }
        }
        timetables.append(contentsOf: classesPast)
        
        if timetables.count == 0 {
            tableView.isHidden = true
            loadingLabel.isHidden = false
            loadingLabel.text = "No classes."
        } else {
            loadingLabel.text = "Loading..."
            tableView.reloadData()
        }
        lastWeekday = currentWeekday
        lastMinute = Calendar.current.component(.minute, from: date)
    }
    
    func retrieveLatestClass() -> ClassOneRealm? {
        guard let user = self.user else { return nil }
        let date = Date()
        let currentWeekday = Calendar.current.component(.weekday, from: date)
        let currentHour = Calendar.current.component(.hour, from: date)
        let classesOne = RealmHelper.retrieveAllClassesOne(user: user.username)
        for classOne in classesOne {
            guard let weekday = classOne.weekday else { break }
            guard let classWeekday = weekdayDict[weekday] else { break }
            let endTime = classOne.endTime
            
            if classWeekday == currentWeekday {
                if endTime > currentHour {
                    return classOne
                }
            } else if classWeekday > currentWeekday {
                return classOne
            }
        }
        return ClassOneRealm()
    }
    

    // MARK: - TableView
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let displayMode = self.extensionContext?.widgetLargestAvailableDisplayMode else { return 0 }
        switch displayMode {
        case .compact:
            return 2
        case .expanded:
            return 4
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard timetables.count > 0 else { return UITableViewCell() }
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "classTimeTableViewCell", for: indexPath) as? ClassTimeTableViewCell else { return UITableViewCell() }
        let row = indexPath.row
        let classOne = timetables[row]
        guard let course = classOne.course else { return UITableViewCell() }
        guard let title = course.title else { return UITableViewCell() }
        guard let teacher = course.teacher else { return UITableViewCell() }
        guard let classroom = classOne.classroom else { return UITableViewCell() }
        guard let weekday = classOne.weekday else { return UITableViewCell() }
        guard let classWeekday = weekdayDict[weekday] else { return UITableViewCell() }
        let startTime = classOne.startTime
        let endTime = classOne.endTime
        cell.classNameLabel.text = title
        cell.classNameLabel.frame.size.width = cell.timeLabel.frame.origin.x - cell.classNameLabel.frame.origin.x
        cell.otherLabel.text = "\(classroom), \(teacher)"
        cell.otherLabel.sizeToFit()
        cell.timeLabel.text = "\(startTime):00 - \(endTime):00"

        var leftTimeColor = UIColor(hex: 0x4c4c4c)
        var leftTimeText = ""
        let currentWeekday = Calendar.current.component(.weekday, from: Date())
        let currentHour = Calendar.current.component(.hour, from: Date())
        let currentMinute = Calendar.current.component(.minute, from: Date())
        
        if currentWeekday == classWeekday {
            if startTime > currentHour {
                let minus = startTime - currentHour
                if minus == 1 {
                    let minutes = 60 - currentMinute
                    if minutes == 1 {
                        leftTimeText = "In 1 minute"
                        leftTimeColor = UIColor.bkRed
                    } else {
                        leftTimeText = "In \(minutes) minutes"
                        leftTimeColor = UIColor.bkRed
                    }
                } else {
                    leftTimeText = "In \(minus) hours"
                }
            } else if endTime > currentHour {
                leftTimeColor = UIColor.alertRed
                let minus = currentHour - startTime
                if minus == 0 {
                    leftTimeText = "\(currentMinute) minutes passed"
                } else if minus == 1 {
                    leftTimeText = "1 hour passed"
                } else {
                    leftTimeText = "\(minus) hours passed"
                }
            } else {
                // past
            }
        } else if currentWeekday < classWeekday {
            if classWeekday - currentWeekday == 1 {
                leftTimeText = "Tomorrow"
            } else {
                leftTimeText = weekday
            }
        } else {
            // next week
            leftTimeText = "Next " + weekday
        }
        cell.leftTimeLabel.text = leftTimeText
        cell.leftTimeLabel.textColor = leftTimeColor

        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
    }


}

let weekdayDict: [String: Int] = [
    "Sunday": 1,
    "Monday": 2,
    "Tuesday": 3,
    "Wednesday": 4,
    "Thursday": 5,
    "Friday": 6,
    "Saturday": 7
]

func printit(_ any: Any) {
    print("-----------------------------------")
    print(any)
    print("-----------------------------------")
}

